/*
 * Copyright 2011 Angel Sanadinov
 *
 * This file is part of VBox WMI.
 *
 * VBox WMI is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * VBox WMI is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with VBox WMI.  If not, see <http://www.gnu.org/licenses/>.
 */

package Beans.Responses.DataRetrievalComponents;

import Beans.Requests.MachineManagement.Components.AudioSettings;
import Beans.Requests.MachineManagement.Components.BIOSSettings;
import Beans.Requests.MachineManagement.Components.BootSettings;
import Beans.Requests.MachineManagement.Components.CPUSettings;
import Beans.Requests.MachineManagement.Components.IOSettings;
import Beans.Requests.MachineManagement.Components.MemorySettings;
import Beans.Requests.MachineManagement.Components.NetworkAdapterSettings;
import Beans.Requests.MachineManagement.Components.SharedFolderSettings;
import Beans.Requests.MachineManagement.Components.VRDPSettings;
import Beans.Requests.MachineManagement.Components.VideoSettings;
import Beans.VirtualResourceBean;
import org.virtualbox_3_2.MachineState;

/**
 * This class represents machine data, when retrieved from the system.
 *
 * @author Angel Sanadinov
 */
public class MachineDataComponent extends DataRetrievalComponent
{
    private String machineName;             //machine name
    private String osTypeId;                //machine OS type id
    private String machineDescription;      //machine description
    private MachineState machineState;      //machine state
    private VirtualResourceBean machineData;//machine data
    private boolean isMachineDataPartial;   //denotes partial machine data
    private int numberOfSnapshots;          //number of snapshots for the machine
    private AudioSettings audioSettings;    //audio settings
    private BIOSSettings biosSettings;      //bios settings
    private BootSettings bootSettings;      //boot settings
    private CPUSettings cpuSettings;        //cpu settings
    private IOSettings ioSettings;          //io settings
    private MemorySettings memorySettings;  //memory settings
    private NetworkAdapterSettings[] networksSettings;//networking settings
    private SharedFolderSettings[] sharedFoldersSettings;//shared folders settings
    private MachineStorageData storageSettings;//storage settings
    private VRDPSettings vrdpSettings;      //vrdp settings
    private VideoSettings videoSettings;    //video settings

    /**
     * Constructs a machine data component, using the specified data. <br><br>
     *
     * Used when the service retrieves multiple machine data objects.
     *
     * @param machineName the name of the machine
     * @param osTypeId the operating system type id of the machine
     * @param machineDescription machine description
     * @param machineState the current state of the machine
     * @param machineData machine database data
     */
    public MachineDataComponent(String machineName, String osTypeId, String machineDescription, MachineState machineState, VirtualResourceBean machineData)
    {
        this.machineName = machineName;
        this.osTypeId = osTypeId;
        this.machineDescription = machineDescription;
        this.machineState = machineState;
        this.machineData = machineData;
        this.isMachineDataPartial = true;
    }

    /**
     * Constructs a machine data component, using the specified data. <br><br>
     *
     * Used when the service retrieves a single machine data object.
     *
     * @param machineName the name of the machine
     * @param osTypeId the operating system type id of the machine
     * @param machineDescription machine description
     * @param machineState the current state of the machine
     * @param numberOfSnapshots the number of snapshots associated with the machine
     * @param machineData machine database data
     * @param audioSettings audio configuration
     * @param biosSettings BIOS configuration
     * @param bootSettings boot configuration
     * @param cpuSettings CPU configuration
     * @param ioSettings I/O configuration
     * @param memorySettings memory configuration
     * @param networksSettings networks configuration
     * @param sharedFoldersSettings shared folders configuration
     * @param storageSettings storage configuration
     * @param vrdpSettings VRDP server configuration
     * @param videoSettings video configuration
     */
    public MachineDataComponent(String machineName, String osTypeId, String machineDescription, 
                                MachineState machineState, int numberOfSnapshots,
                                VirtualResourceBean machineData, AudioSettings audioSettings,
                                BIOSSettings biosSettings, BootSettings bootSettings,
                                CPUSettings cpuSettings, IOSettings ioSettings,
                                MemorySettings memorySettings, NetworkAdapterSettings[] networksSettings,
                                SharedFolderSettings[] sharedFoldersSettings, MachineStorageData storageSettings,
                                VRDPSettings vrdpSettings, VideoSettings videoSettings)
    {
        this.machineName = machineName;
        this.osTypeId = osTypeId;
        this.machineDescription = machineDescription;
        this.machineState = machineState;
        this.numberOfSnapshots = numberOfSnapshots;
        this.machineData = machineData;
        this.isMachineDataPartial = false;
        this.audioSettings = audioSettings;
        this.biosSettings = biosSettings;
        this.bootSettings = bootSettings;
        this.cpuSettings = cpuSettings;
        this.ioSettings = ioSettings;
        this.memorySettings = memorySettings;
        this.networksSettings = networksSettings;
        this.sharedFoldersSettings = sharedFoldersSettings;
        this.storageSettings = storageSettings;
        this.vrdpSettings = vrdpSettings;
        this.videoSettings = videoSettings;
    }

    //<editor-fold defaultstate="collapsed" desc="Accessor Methods">
    /**
     * Retrieves the name of the machine.
     *
     * @return the machine name
     */
    public String getMachineName()
    {
        return machineName;
    }

    /**
     * Retrieves the operating system type id of the machine.
     *
     * @return the OS type id
     */
    public String getOsTypeId()
    {
        return osTypeId;
    }

    /**
     * Retrieves the description of the machine.
     *
     * @return the machine description
     */
    public String getMachineDescription()
    {
        return machineDescription;
    }

    /**
     * Retrieves the state of the machine.
     *
     * @return the machine state
     */
    public MachineState getMachineState()
    {
        return machineState;
    }

    /**
     * Retrieves the machine database machine data.
     *
     * @return the machine data
     */
    public VirtualResourceBean getMachineData()
    {
        return machineData;
    }

    /**
     * Returns whether the machine data is full or partial.
     *
     * @return <code>true</code> if machine data is partial or <code>false</code>
     *         if machine data is full
     */
    public boolean isMachineDataPartial()
    {
        return isMachineDataPartial;
    }

    /**
     * Retrieves the audio settings of the machine.
     *
     * @return the audio settings, if available or <code>null</code> otherwise
     */
    public AudioSettings getAudioSettings()
    {
        return audioSettings;
    }

    /**
     * Retrieves the BIOS settings of the machine.
     *
     * @return the BIOS settings, if available or <code>null</code> otherwise
     */
    public BIOSSettings getBiosSettings()
    {
        return biosSettings;
    }

    /**
     * Retrieves the boot settings of the machine.
     *
     * @return the boot settings, if available or <code>null</code> otherwise
     */
    public BootSettings getBootSettings()
    {
        return bootSettings;
    }

    /**
     * Retrieves the CPU settings of the machine.
     *
     * @return the CPU settings, if available or <code>null</code> otherwise
     */
    public CPUSettings getCpuSettings()
    {
        return cpuSettings;
    }

    /**
     * Retrieves the I/O settings of the machine.
     *
     * @return the I/O settings, if available or <code>null</code> otherwise
     */
    public IOSettings getIoSettings()
    {
        return ioSettings;
    }

    /**
     * Retrieves the memory settings of the machine.
     *
     * @return the memory settings, if available or <code>null</code> otherwise
     */
    public MemorySettings getMemorySettings()
    {
        return memorySettings;
    }

    /**
     * Retrieves the networking settings of the machine (for each network adapter).
     *
     * @return the networking settings, if available or <code>null</code> otherwise
     */
    public NetworkAdapterSettings[] getNetworksSettings()
    {
        return networksSettings;
    }

    /**
     * Retrieves the shared folders settings of the machine.
     *
     * @return the shared folders settings, if available or <code>null</code> otherwise
     */
    public SharedFolderSettings[] getSharedFoldersSettings()
    {
        return sharedFoldersSettings;
    }

    /**
     * Retrieves the storage settings of the machine.
     *
     * @return the storage settings, if available or <code>null</code> otherwise
     */
    public MachineStorageData getStorageSettings()
    {
        return storageSettings;
    }

    /**
     * Retrieves the VRDP settings of the machine.
     *
     * @return the VRDP settings, if available or <code>null</code> otherwise
     */
    public VRDPSettings getVrdpSettings()
    {
        return vrdpSettings;
    }

    /**
     * Retrieves the video settings of the machine.
     *
     * @return the video settings, if available or <code>null</code> otherwise
     */
    public VideoSettings getVideoSettings()
    {
        return videoSettings;
    }

    /**
     * Retrieves the number of snapshots the machine has.
     *
     * @return the number of snapshots
     */
    public int getNumberOfSnapshots()
    {
        return numberOfSnapshots;
    }
    //</editor-fold>

    /**
     * Checks the validity of the networks settings.
     *
     * @return <code>true</code> if the settings are valid or <code>false</code> otherwise
     */
    private boolean areNetworksSettingsValid()
    {
        if(networksSettings != null)
        {
            for(NetworkAdapterSettings adapterSettings : networksSettings)
            {
                if(adapterSettings != null && !adapterSettings.isValid())
                    return false;
                else
                    ;
            }
        }
        else
            ;

        return true;
    }

    /**
     * Checks the validity of the shared folders settings.
     *
     * @return <code>true</code> if the settings are valid or <code>false</code> otherwise
     */
    private boolean areSharedFoldersSettingsValid()
    {
        if(sharedFoldersSettings != null)
        {
            for(SharedFolderSettings folderSettings : sharedFoldersSettings)
            {
                if(folderSettings != null && !folderSettings.isValid())
                    return false;
                else
                    ;
            }
        }
        else
            ;

        return true;
    }

    /**
     * Checks the validity of all machine settings. <br><br>
     *
     * Used when full data is available.
     *
     * @return <code>true</code> if the settings are valid or <code>false</code> otherwise
     */
    private boolean isMachineSettingsDataValid()
    {
        if((audioSettings == null || audioSettings.isValid())
        /**/    && (biosSettings == null || biosSettings.isValid())
        /**/    && (bootSettings == null || bootSettings.isValid())
        /**/    && (cpuSettings == null || cpuSettings.isValid())
        /**/    && (ioSettings == null || ioSettings.isValid())
        /**/    && (memorySettings == null || memorySettings.isValid())
        /**/    && areNetworksSettingsValid()
        /**/    && areSharedFoldersSettingsValid()
        /**/    && (storageSettings == null || storageSettings.isValid())
        /**/    && (vrdpSettings == null || vrdpSettings.isValid())
        /**/    && (videoSettings == null || videoSettings.isValid()))
        {
            return true;
        }
        else
            return false;
    }

    /**
     * Checks the validity of the basic (main) machine data.
     *
     * @return <code>true</code> if the data is valid or <code>false</code> otherwise
     */
    private boolean isMainMachineDataValid()
    {
        if(machineData != null && machineData.isValid()
                && machineName != null && osTypeId != null)
            return true;
        else
            return false;
    }

    @Override
    public boolean isValid()
    {
        if(isMainMachineDataValid() && (isMachineDataPartial || isMachineSettingsDataValid()))
            return true;
        else
            return false;
    }
}
